﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Configuration;

using Emc.Documentum.FS.Services.Core;
using Emc.Documentum.FS.DataModel.Core;
using Emc.Documentum.FS.DataModel.Core.Query;
using Emc.Documentum.FS.DataModel.Core.Properties;
using Emc.Documentum.FS.DataModel.Core.Profiles;
using Emc.Documentum.FS.Runtime;
using Emc.Documentum.FS.Runtime.Context;
using Emc.Documentum.FS.DataModel.Core.Context;
using Emc.Documentum.FS.DataModel.Core.Content;

using EsuApiLib;
using EsuApiLib.Rest;
using System.Xml;


namespace DocumentumPushToAtmos
{
    public class DctmAtmos
    {
        #region Class Properties

        private string defaultRepository = null;
        private string secondaryRepository = null;
        private string userName = null;
        private string password = null;
        private IServiceContext serviceContext;
        private IObjectService objectService;
        private IQueryService queryService;

        #endregion Class Properties



        private void initializeContext()
        {
            //grab values from associated config file:
            defaultRepository = ConfigurationManager.AppSettings["Repository"];
            secondaryRepository = ConfigurationManager.AppSettings["Repository"];
            userName = ConfigurationManager.AppSettings["DctmUser"];
            password = ConfigurationManager.AppSettings["DctmPassword"];

            ContextFactory contextFactory = ContextFactory.Instance;
            serviceContext = contextFactory.NewContext();

            RepositoryIdentity repoId = new RepositoryIdentity();
            RepositoryIdentity repositoryIdentity =
                new RepositoryIdentity(defaultRepository, userName, password, "");
            serviceContext.AddIdentity(repositoryIdentity);

            ContentTransferProfile contentTransferProfile = new ContentTransferProfile();
            contentTransferProfile.TransferMode = ContentTransferMode.MTOM;
            contentTransferProfile.Geolocation = "Toronto";
            serviceContext.SetProfile(contentTransferProfile);

            if (!String.IsNullOrEmpty(secondaryRepository))
            {
                RepositoryIdentity repoId1 = new RepositoryIdentity();
                repoId1.RepositoryName = secondaryRepository;
                repoId1.UserName = userName;
                repoId1.Password = password;
                serviceContext.AddIdentity(repoId1);
            }
        }


        public void moveFromDocumentumToAtmos()
        {

            initializeContext();

            String forAtmosFolderId = ConfigurationManager.AppSettings["ForAtmosFolderId"];

            List<String> allObjIDs = new List<String>();

            ContentTransferProfile profile = new ContentTransferProfile();
            profile.TransferMode = ContentTransferMode.MTOM;
            serviceContext.SetProfile(profile);

            ServiceFactory serviceFactory = ServiceFactory.Instance;
            queryService = serviceFactory.GetRemoteService<IQueryService>(serviceContext);

            ContentProfile contentProfile = new ContentProfile();
            contentProfile.FormatFilter = FormatFilter.ANY;

            OperationOptions operationOptions = new OperationOptions();
            operationOptions.ContentProfile = contentProfile;

            try
            {
                PassthroughQuery query = new PassthroughQuery();
                query.AddRepository(defaultRepository);
                query.QueryString = "SELECT r_object_id FROM dl_model WHERE ANY i_folder_id = '" + forAtmosFolderId + "'";
                QueryExecution queryExec = new QueryExecution(0, 4, 4);
                QueryResult allObjects = queryService.Execute(query, queryExec, operationOptions);

                String modelID = null;

                if (allObjects.DataObjects.Count() == 0)
                {
                    return;
                }

                foreach (DataObject objForAtmos in allObjects.DataObjects)
                {
                    modelID = objForAtmos.Identity.GetValueAsString();
                    allObjIDs.Add(modelID);

                    ObjectIdentity objId = new ObjectIdentity(defaultRepository);
                    objId.Value = new Emc.Documentum.FS.DataModel.Core.ObjectId(modelID);
                    objId.ValueType = ObjectIdentityType.OBJECT_ID;

                    objectService = serviceFactory.GetRemoteService<IObjectService>(serviceContext);

                    ObjectIdentitySet idSet = new ObjectIdentitySet(objId);

                    DataPackage modelObjects = objectService.Get(idSet, operationOptions);

                    if (modelObjects.DataObjects.Count() != 1)
                    {
                        return;
                    }

                    DataObject modelObject = modelObjects.DataObjects[0];

                    if (null == modelObject.Contents || modelObject.Contents.Count == 0)
                    {
                        continue;
                    }

                    Byte[] modelContent = modelObject.Contents[0].GetAsByteArray();


                    //Calculate location of user's Atmos storage via xDB registry:
                    //String registryUsername = ConfigurationManager.AppSettings["MonsterMashRegistryUser"];
                    //String registryPassword = ConfigurationManager.AppSettings["MonsterMashRegistryPassword"];
                    String registryName = ConfigurationManager.AppSettings["MonsterMashRegistry"];

                    PropertySet objProperties = modelObject.Properties;
                    StringProperty objUploader = (StringProperty)objProperties.Get("v_uploader");
                    String registryUsername = objUploader.Value;
                    StringProperty objUploaderPassword = (StringProperty)objProperties.Get("v_uploader_password");
                    String registryPassword = objUploaderPassword.Value;

                    xDB_SOAP.XhiveServerSessionIfClient client = new DocumentumPushToAtmos.xDB_SOAP.XhiveServerSessionIfClient();

                    String sessionID = client.connect(registryUsername, registryPassword, registryName);
                    String linksDoc = client.getDocument(sessionID, "/" + registryUsername + "/links.xml", null, null);
                    client.Close();

                    if (String.IsNullOrEmpty(linksDoc))
                    {
                        return;
                    }

                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(linksDoc);

                    XmlNodeList topNodes = doc.GetElementsByTagName("Atmos_Online");
                    XmlNode topNode = topNodes[0];
                    XmlNodeList propertyNodes = topNode.ChildNodes;

                    String atmosServer = null;
                    String atmosPortStr = null;
                    String atmosTokenID = null;
                    String atmosSharedSecret = null;

                    foreach (XmlNode propertyNode in propertyNodes)
                    {
                        if (propertyNode.Name.Equals("URL"))
                        {
                            atmosServer = propertyNode.InnerText;
                        }
                        else if (propertyNode.Name.Equals("Port"))
                        {
                            atmosPortStr = propertyNode.InnerText;
                        }
                        else if (propertyNode.Name.Equals("TokenID"))
                        {
                            atmosTokenID = propertyNode.InnerText;
                        }
                        else if (propertyNode.Name.Equals("SharedSecret"))
                        {
                            atmosSharedSecret = propertyNode.InnerText;
                        }

                    }

                    int atmosPort = Int32.Parse(atmosPortStr);

                    EsuApi atmosClient = new EsuApiLib.Rest.EsuRestApi(atmosServer, atmosPort, atmosTokenID, atmosSharedSecret);

                    StringProperty objName = (StringProperty)objProperties.Get("object_name");
                    String objFilename = objName.Value;

                    EsuApiLib.ObjectPath objPath = new EsuApiLib.ObjectPath("/MonsterMash/" + objFilename);

                    try
                    {
                        atmosClient.CreateObjectOnPath(objPath, null, null, modelContent, null);

                        //delete object in Documentum since successful:
                        //objectService.Delete(idSet, operationOptions);
                    }
                    catch (EsuException esuEx)
                    {
                        String err = esuEx.ToString();
                    }
                    catch (Exception ex)
                    {
                        String err = ex.ToString();
                    }



                }

            }
            catch (Exception ex)
            {

            }

        }


    }
}
